home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #2 / Amiga Plus CD - 1995 - No. 2.iso / startrek / trek73 / src / enemycom.c < prev    next >
C/C++ Source or Header  |  1995-04-11  |  8KB  |  435 lines

  1. /*
  2.  * TREK73: enemycom.c
  3.  *
  4.  * Enemy strategy sub-routines
  5.  *
  6.  * e_phasers, e_lockphasers, e_locktubes, e_checkprobe, e_evade,
  7.  * e_pursue, e_launchprobe, e_destruct, e_torpedo, e_jettison,
  8.  * e_checkarms, e_runaway, e_attack, e_loadtubes, e_closetorp
  9.  *
  10.  */
  11.  
  12. #include "defines.h"
  13. #include "structs.h"
  14.  
  15. extern float fabs();
  16. extern char science[];
  17. extern char helmsman[];
  18.  
  19. /*
  20.  * returns the number of banks we're going to fire
  21.  * it also sets them up.
  22.  */
  23. int e_phasers(sp, fed)
  24. struct ship *sp;
  25. struct ship *fed;
  26. {
  27.     register int i;
  28.     register int banks;
  29.     register int hit;
  30.     register int howmany;
  31.     int bear;
  32.  
  33.     banks = 0;
  34.     howmany = randm(2) + 2;
  35.     sp->p_spread = 10 + randm(12);
  36.     for (i=0; i<4; i++) {
  37.         if (sp->phasers[i].status & P_DAMAGED)
  38.             continue;
  39.         if (fed != NULL) {
  40.             if (sp->phasers[i].target == NULL)
  41.                 continue;
  42.             bear = bearing(sp->x, fed->x, sp->y, fed->y);
  43.             hit = phaser_hit(sp, fed->x, fed->y, &sp->phasers[i], bear);
  44.             if (hit <= 0)
  45.                 continue;
  46.         }
  47.         banks++;
  48.         sp->phasers[i].status |= P_FIRING;
  49.         if (banks > howmany)
  50.             break;
  51.     }
  52.     return banks;
  53. }
  54.  
  55. /*
  56.  * returns positive if we had to lock phasers
  57.  */
  58. int e_lockphasers(sp, fed)
  59. struct ship *sp;
  60. struct ship *fed;
  61. {
  62.     register int i;
  63.     register int banks;
  64.  
  65.     banks = 0;
  66.     for (i=0; i<4; i++) {
  67.         if (sp->phasers[i].status & P_DAMAGED)
  68.             continue;
  69.         if (sp->phasers[i].target != NULL)
  70.             continue;
  71.         sp->phasers[i].target = fed;
  72.         banks++;
  73.     }
  74.     return banks;
  75. }
  76.  
  77. /*
  78.  * returns positive if we had to lock tubes
  79.  */
  80. int e_locktubes(sp, fed)
  81. struct ship *sp;
  82. struct ship *fed;
  83. {
  84.     register int i;
  85.     register int tubes;
  86.  
  87.     tubes = 0;
  88.     for (i=0; i<4; i++) {
  89.         if (sp->tubes[i].status & T_DAMAGED)
  90.             continue;
  91.         if (sp->tubes[i].target != NULL)
  92.             continue;
  93.         sp->tubes[i].target = fed;
  94.         tubes++;
  95.     }
  96.     return tubes;
  97. }
  98.  
  99. /*
  100.  * returns 1 if evasive action being taken (to avoid probe)
  101.  */
  102. e_checkprobe(sp)
  103. struct ship *sp;
  104. {
  105.     extern    struct list head;
  106.     extern    struct list *tail;
  107.     register struct list *lp;
  108.     register int range;
  109.     register struct torpedo *tp;
  110.  
  111.     for (lp = &head; lp != tail; lp = lp->fwd) {
  112.         if (lp->type != I_PROBE)
  113.             continue;
  114.         tp = lp->data.tp;
  115.         range = rangefind(sp->x, tp->x, sp->y, tp->y);
  116.         if (range < 1000) {
  117.             e_evade(sp, tp->x, tp->y, I_PROBE);
  118.             return 1;
  119.         }
  120.     }
  121.     return 0;
  122. }
  123.  
  124.  
  125. /*
  126.  * advance to the rear!
  127.  */
  128. e_evade(sp, x, y, type)
  129. struct ship *sp;
  130. int x;
  131. int y;
  132. int type;        /* Currently unused */
  133. {
  134.     register int i;
  135.     register int newcourse;
  136.     int    bear;
  137.  
  138.     bear = bearing(sp->x, x, sp->y, y);
  139.     printf("%s taking evasive action!\n", sp->name);
  140.     i = randm(3);
  141.     switch (i) {
  142.         case 1:
  143.             newcourse = rectify(bear - 90);
  144.             break;
  145.         case 2:
  146.             newcourse = rectify(bear + 90);
  147.             break;
  148.         case 3:
  149.             newcourse = rectify(bear + 180);
  150.             break;
  151.         default:
  152.             printf("error in evade()\n");
  153.             break;
  154.     }
  155.     sp->target = NULL;
  156.     sp->newcourse = newcourse;
  157.     sp->newwarp = 2 + randm(8);
  158.     if (sp->status & S_WARP)
  159.         sp->newwarp = 1.0;
  160.     type = type;                /* LINT */
  161.     return 1;
  162. }
  163.  
  164.  
  165. e_pursue(sp, fed, speed)
  166. struct ship *sp;
  167. struct ship *fed;
  168. int speed;
  169. {
  170.     int    bear;
  171.     int    coursediff;
  172.  
  173.     bear = bearing(sp->x, fed->x, sp->y, fed->y);
  174.     /*
  175.      * do a quick turn if our speed is > warp 10 and
  176.      * (thus) we are never going to bear on the fed ship
  177.      * speed = 7 is a magic cookie.  feel free to change.
  178.      */
  179.     coursediff = abs(sp->course - bear);
  180.     if (speed >= 9 && coursediff > 10)
  181.         speed = 5;
  182.     sp->target = fed;
  183.     sp->newcourse = bear;
  184.     sp->newwarp = speed;
  185.     if (speed > 1 && (sp->status & S_WARP))
  186.         sp->newwarp = 0.99;
  187.     return 1;
  188. }
  189.  
  190.  
  191. int e_launchprobe(sp, fed)
  192. struct ship *sp;
  193. struct ship *fed;
  194. {
  195.     extern    struct list *newitem();
  196.     register int i;
  197.     register struct list *lp;
  198.     register struct torpedo *tp;
  199.  
  200.     if ((sp->status & S_PROBE) || sp->energy <= 10)
  201.         return 0;
  202.     /*
  203.      * fed ship has to be going slow before we'll launch
  204.      * a probe at it.
  205.      */
  206.     if (fabs(fed->warp) > 1.0)
  207.         return 0;
  208.     lp = newitem(I_PROBE);
  209.     tp = lp->data.tp = MKNODE(struct torpedo, *, 1);
  210.     printf("%s launching probe\n", sp->name);
  211.     tp->speed = sp->warp;
  212.     tp->newspeed = 3.0;
  213.     tp->target = fed;
  214.     tp->course = bearing(sp->x, fed->x, sp->y, fed->y);
  215.     tp->x = sp->x;
  216.     tp->y = sp->y;
  217.     tp->prox = 200 + randm(200);
  218.     tp->timedelay = 15 * 10;
  219.     i = min(randm(15) + 10, sp->energy);
  220.     tp->fuel = i;
  221.     sp->energy -= i;
  222.     sp->pods -= i;
  223.     return 1;
  224. }
  225.  
  226.  
  227. /*
  228.  * goodbye, cruel world
  229.  */
  230. int e_destruct(sp)
  231. struct ship *sp;
  232. {
  233.     if (sp->delay < 5 * 9)
  234.         return 0;
  235.     sp->delay = 5 * 9;
  236.     printf("%s: The %s is overloading what remains of it's\n",science, sp->name);
  237.     printf("   antimatter pods -- obviously a suicidal gesture.\n");
  238.     printf("   Detonation in five seconds\n");
  239.     return 1;
  240. }
  241.  
  242.  
  243. int e_torpedo(sp)
  244. struct ship *sp;
  245. {
  246.     extern    struct ship *shiplist[];
  247.     extern    int shipnum;
  248.     register int i;
  249.     register int tubes;
  250.     register int howmany;
  251.     register struct ship *sp1;
  252.     register int range;
  253.  
  254.     /*
  255.      * don't shoot if someone might be in the way
  256.      * (i.e. proximity fuse will go off right as the
  257.      * torps leave the tubes!)
  258.      */
  259.     for (i=1; i <= shipnum; i++) {
  260.         sp1 = shiplist[i];
  261.         if ((sp1->status & S_DEAD) || sp1 == sp)
  262.             continue;
  263.         range = rangefind(sp->x, sp1->x, sp->y, sp1->y);
  264.         if (range <= 400)
  265.             return 0;
  266.     }
  267.     tubes = 0;
  268.     howmany = randm(2) + 1;
  269.     for (i=0; i<4; i++) {
  270.         if ((sp->tubes[i].status & T_DAMAGED)
  271.             || (sp->tubes[i].load == 0))
  272.             continue;
  273.         if (sp->tubes[i].target == NULL)
  274.             continue;
  275.         tubes++;
  276.         sp->tubes[i].status |= T_FIRING;
  277.         if (tubes > howmany)
  278.             break;
  279.     }
  280.     return tubes;
  281. }
  282.  
  283.  
  284. int e_jettison(sp)
  285. struct ship *sp;
  286. {
  287.     extern    struct list *newitem();
  288.     register struct list *lp;
  289.     register struct torpedo *tp;
  290.  
  291.     if (sp->status & S_ENG)
  292.         return 0;
  293.     if (!(shiplist[0]->status & S_SENSOR)) {
  294.         printf("%s: Sensors indicate debris being left by\n", science);
  295.         printf("   the %s.  Insufficient mass?\n", sp->name);
  296.     }
  297.     lp = newitem(I_ENG);
  298.     tp = lp->data.tp = MKNODE(struct torpedo, *, 1);
  299.     tp->id = new_slot();
  300.     /*
  301.      * ship slows to warp 1.0 when jettisonning engineering
  302.      */
  303.     tp->newspeed = 0.0;
  304.     tp->speed = sp->warp;
  305.     tp->target = NULL;
  306.     tp->course = sp->course;
  307.     tp->x = sp->x;
  308.     tp->y = sp->y;
  309.     tp->prox = 0;
  310.     tp->timedelay = 15 * 9;
  311.     tp->fuel = sp->pods;
  312.     sp->energy = sp->pods = 0;
  313.     sp->regen = 0.0;
  314.     tp->from = sp;
  315.     if (sp->newwarp < -1.0)
  316.         sp->newwarp = -0.99;
  317.     if (sp->newwarp > 1.0)
  318.         sp->newwarp = 0.99;
  319.     sp->status |= S_ENG;
  320.     sp->status |= S_WARP;
  321.     return 1;
  322. }
  323.  
  324. int e_checkarms(sp)
  325. struct ship *sp;
  326. {
  327.     register int i;
  328.     register int arms;
  329.  
  330.     arms = 0;
  331.     for (i=0; i<4; i++)
  332.         if (sp->phasers[i].load >= 0)
  333.             arms++;
  334.     for (i=0; i<6; i++)
  335.         if (sp->tubes[i].load >= 0)
  336.             arms++;
  337.     return arms;
  338. }
  339.  
  340. int e_runaway(sp, fed)
  341. struct ship *sp;
  342. struct ship *fed;
  343. {
  344.     register int speed;
  345.  
  346.     speed = randm(4) + 2;
  347.     speed = -speed;
  348.     e_pursue(sp, fed, speed);
  349.     printf("%s: The %s is retreating.\n", helmsman, sp->name);
  350.     return 1;
  351. }
  352.  
  353. int e_attack(sp, fed)
  354. struct ship *sp;
  355. struct ship *fed;
  356. {
  357.     int    speed;
  358.     float    tmpf;
  359.  
  360.     tmpf = fabs(fed->warp);
  361.     if (sp->warp >= tmpf + 2.0 || (sp->status & S_WARP))
  362.         return 0;
  363.     speed = min(11, tmpf + randm(2) + 2.0);
  364.     e_pursue(sp, fed, speed);
  365.     printf("%s:  %s attacking.\n", helmsman, sp->name);
  366.     return 1;
  367. }
  368.  
  369. int e_loadtubes(sp)
  370. struct ship *sp;
  371. {
  372.     register int i;
  373.     register int j;
  374.     register int loaded;
  375.     register int below;
  376.  
  377.     below = 10;
  378.     loaded = 0;
  379.     for (i=0; i<6; i++) {
  380.         if (sp->energy <= below)
  381.             break;
  382.         if (sp->tubes[i].status & T_DAMAGED)
  383.             continue;
  384.         j = min(sp->energy, 10-sp->tubes[i].load);
  385.         if (j == 0)
  386.             continue;
  387.         sp->energy -= j;
  388.         sp->pods -= j;
  389.         sp->tubes[i].load += j;
  390.         loaded++;
  391.     }
  392.     return loaded;
  393. }
  394.  
  395. e_closetorps(sp, fed)
  396. struct ship *sp;
  397. struct ship *fed;
  398. {
  399.     extern    struct list head;
  400.     extern    struct list *tail;
  401.     register struct list *lp;
  402.     register int range;
  403.     register struct torpedo *tp;
  404.     struct    torpedo *bad;
  405.  
  406.     bad = NULL;
  407.     for (lp = &head; lp != tail; lp = lp->fwd) {
  408.         if (lp->type != I_TORPEDO)
  409.             continue;
  410.         tp = lp->data.tp;
  411.         if (tp->from != fed)
  412.             continue;
  413.         range = rangefind(sp->x, tp->x, sp->y, tp->y);
  414.         if (range < 1200) {
  415.             bad = tp;
  416.             /*
  417.              * fire phasers - hope they're pointing in
  418.              * the right direction!
  419.              */
  420.             if (e_phasers(sp, (struct ship *) NULL))
  421.                 return 1;
  422.             return 1;
  423.         }
  424.     }
  425.     /*
  426.      * we can't get a phaser shot off.
  427.      * try and evade (although hopeless)
  428.      */
  429.     if (bad != NULL) {
  430.         e_evade(sp, tp->x, tp->y, I_TORPEDO);
  431.         return 1;
  432.     }
  433.     return 0;
  434. }
  435.